package com.xckj.cycling.repository

import android.annotation.SuppressLint
import android.content.Context
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import com.google.gson.Gson
import com.junca.android.service.Request
import com.mapbox.geojson.FeatureCollection
import com.mapbox.navigation.utils.internal.toPoint
import com.xckj.cycling.context.AppContext
import com.xckj.cycling.model.MapBoxAddressModel
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.sendBlocking
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.firstOrNull
import kotlin.coroutines.suspendCoroutine

class MapRepository {

    companion object {
        const val API =
            "https://api.mapbox.com/geocoding/v5/mapbox.places/%s,%s.json?types=poi&access_token=pk.eyJ1IjoibGFuZ2RvbmdsZWkiLCJhIjoiY2xmOWRvcjg1MmV2bDNybGh3dWs5eDNhaCJ9.ILQRw5E7y-vRdykulCTe6w"
    }

    //https://api.mapbox.com/geocoding/v5/mapbox.places/-73.989,40.733.json?types=poi&access_token=pk.eyJ1IjoibGFuZ2RvbmdsZWkiLCJhIjoiY2xmOWRvcjg1MmV2bDNybGh3dWs5eDNhaCJ9.ILQRw5E7y-vRdykulCTe6w
    suspend fun queryPointName(location: Location): MapBoxAddressModel {
        return withContext(Dispatchers.IO) {
            val s = Request.getSuspend<String>(
                String.format(
                    API,
                    location.longitude,
                    location.latitude
                )
            )
            Gson().fromJson(s.data, MapBoxAddressModel::class.java)
        }
    }

    suspend fun queryPointName(longitude: Double, latitued: Double): MapBoxAddressModel {
        return withContext(Dispatchers.IO) {
            val s = Request.getSuspend<String>(
                String.format(
                    API,
                    longitude,
                    latitued
                )
            )
            Gson().fromJson(s.data, MapBoxAddressModel::class.java)
        }
    }

    @SuppressLint("MissingPermission")
    suspend fun location(): Location? {
        return withTimeoutOrNull(15000L) {
            val l = AppContext.globalContext()
                .getSystemService(Context.LOCATION_SERVICE) as LocationManager
            l.locationUpdates(LocationManager.FUSED_PROVIDER, 0, 0f).firstOrNull()
//            suspendCoroutine {
//                val l = AppContext.globalContext()
//                    .getSystemService(Context.LOCATION_SERVICE) as LocationManager
//                var l1: LocationListener? = null
//                val listener: LocationListener = object : LocationListener {
//                    override fun onLocationChanged(location: Location) {
//                        it.resumeWith(Result.success(location))
//                        l1?.apply {
//                            l.removeUpdates(this)
//                        }
//                    }
//                }
//                l1 = listener
//                val s = l.getLastKnownLocation(LocationManager.FUSED_PROVIDER)
//                if (s != null) {
//                    it.resumeWith(Result.success(s))
//                    return@suspendCoroutine
//                }
//                l.requestLocationUpdates(LocationManager.FUSED_PROVIDER, 0L, 0f, listener)
//            }
        }
    }

    fun LocationManager.locationUpdates(
        provider: String,
        minTimeMs: Long,
        minDistance: Float = 0f
    ): Flow<Location> =
        callbackFlow {
            val listener = LocationListener { location -> trySendBlocking(location) }
            requestLocationUpdates(provider, minTimeMs, minDistance, listener)

            awaitClose {
                removeUpdates(listener)
            }
        }

}